package com.eoner.managerlibrary.netsign.version2;

import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.eoner.baselib.utils.sp.SPUtils;
import com.eoner.baselibrary.utils.CookieNewUtil;
import com.eoner.baselibrary.utils.ScreenUtils;
import com.eoner.baselibrary.utils.StringsUtils;
import com.eoner.baselibrary.utils.Utils;
import com.eoner.common.config.Config;
import com.eoner.managerlibrary.servertimer.ServerTimerManager;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
import okio.BufferedSink;

/**
 * 文件名：FCSignInterceptor
 * 描 述：签名重构公用类
 * 作 者：gyq
 * 时 间：2021-2-5
 */
public class FCSignInterceptor implements Interceptor {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    public static final String SIGN_SECRET_KEY =  "87aQr3HQgtTb6EB5zXeW9D7yKwjEfpZR";

    private void readMultipartBodyRequestParam(Request request,Map<String,Object> paramsMapObj) {
        if (request.body() instanceof MultipartBody){
            MultipartBody requestBody = (MultipartBody) request.body();
            MultipartBody.Builder multipartBodybuilder = new MultipartBody.Builder();
            if (requestBody != null) {
                for (int i = 0; i < requestBody.size(); i++) {
                    MultipartBody.Part part = requestBody.part(i);
                    multipartBodybuilder.addPart(part);
                    MediaType mediaType = part.body().contentType();
                    if (mediaType == null) {
                        String normalParamKey;
                        String normalParamValue;
                        try {
                            normalParamValue = getParamContent(requestBody.part(i).body());
                            Headers headers = part.headers();
                            if (!TextUtils.isEmpty(normalParamValue) && headers != null) {
                                for (String name : headers.names()) {
                                    String headerContent = headers.get(name);
                                    if (!TextUtils.isEmpty(headerContent)) {
                                        String[] normalParamKeyContainer = headerContent.split("name=\"");
                                        if (normalParamKeyContainer.length == 2) {
                                            normalParamKey = normalParamKeyContainer[1].split("\"")[0];
                                            paramsMapObj.put(normalParamKey,normalParamValue);
                                            break;
                                        }
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取常规post请求参数
     */
    private String getParamContent(RequestBody body) throws IOException {
        Buffer buffer = new Buffer();
        body.writeTo(buffer);
        return buffer.readUtf8();
    }
    public boolean isMainThread() {
        return Looper.getMainLooper() == Looper.myLooper();
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        RequestBody requestBody = request.body();
        if (requestBody == null) {
            requestBody = new RequestBody() {
                @Override
                public MediaType contentType() {
                    return null;
                }
                @Override
                public void writeTo(BufferedSink sink) throws IOException {
                }
            };
        }
        boolean flag = false;
        String host = request.url().url().getHost();
        flag = host.startsWith("api") | host.startsWith("rapi") | host.startsWith("rsapi") | host.startsWith("sapi");
        if (flag) {
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            Charset charset = UTF8;
            MediaType contentType = requestBody.contentType();
            //TODO:1.前置变量
            //签名时用到的参数
            Map<String,Object> paramsMapObj = new HashMap<>();
            //时间戳
            long timestamp = ServerTimerManager.getInstance().getCurrentTimeMillis() / 1000;

            //TODO:2.获取请求参数
            if (contentType != null) {
                charset = contentType.charset(UTF8);
            }
            String paramsJson = buffer.readString(charset);

            readMultipartBodyRequestParam(request,paramsMapObj);
            try {
                paramsMapObj = JSONObject.parseObject(paramsJson, Map.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if ("get".equalsIgnoreCase(request.method())) {
                HttpUrl url = request.url();
                Set<String> paramKeys = url.queryParameterNames();
                for (String key : paramKeys) {
                    String value = url.queryParameter(key);
                    paramsMapObj.put(key,value);
                }
            }
            //TODO:3.设置公参
            paramsMapObj.put("device", Utils.getDevicedId());
            paramsMapObj.put("version", CookieNewUtil.getVersionName(Utils.getContext()));
            paramsMapObj.put("platform", "android");
            paramsMapObj.put("os",android.os.Build.VERSION.RELEASE);
            paramsMapObj.put("timestamp",timestamp+"");
            paramsMapObj.put("device_id", Config.DEVICE_ID);
            //比ios多传这2个参数
            paramsMapObj.put("device_token",Config.DEVICE_TOKEN);
            paramsMapObj.put("x-token", SPUtils.getInstance().getString(Config.CUSTOMER_TOKEN));
            //TODO:4.进行签名
            String md5 = signByParam(paramsMapObj);
            HttpUrl.Builder authorizedUrlBuilder = request.url()
                    .newBuilder()
                    .scheme(request.url().scheme())
                    .host(request.url().host())
                    .addQueryParameter("sign", md5)
                    .addQueryParameter("device", Utils.getDevicedId())
                    .addQueryParameter("platform", "android")
                    .addQueryParameter("os", android.os.Build.VERSION.RELEASE)
                    .addQueryParameter("timestamp", "" + timestamp)
                    .addQueryParameter("device_token", Config.DEVICE_TOKEN)
                    .addQueryParameter("device_id", Config.DEVICE_ID)
                    .addQueryParameter("version", CookieNewUtil.getVersionName(Utils.getContext()));

            Response response;
            if (!TextUtils.isEmpty(md5)) {
                Request.Builder builder = request.newBuilder();
                builder.url(authorizedUrlBuilder.build());
                builder.method(request.method(), request.body());
                RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), paramsJson);
                //TODO:5 排除图片上传的接口
                if (contentType != null && "multipart".equals(contentType.type())) {
                    response = chain.proceed(builder.build());
                    return response;
                }
                if ("post".equalsIgnoreCase(request.method())) {
                    builder.post(body);
                } else {
                    //builder.get().put(body);
                }
                response = chain.proceed(builder.build());
            } else {
                response = chain.proceed(request);
            }
            return response;
        }

        return null;
    }

    /**
    * 签名
    * */
    private String signByParam(Map<String,Object> paramsMapObj) {
        String str = stringByParam(paramsMapObj);
        String sign = SIGN_SECRET_KEY+str+SIGN_SECRET_KEY;
        sign = StringsUtils.parseStrToMd5U32(sign);
        return sign;
    }

    private String stringByParam(Map<String,Object> paramsMapObj) {
        if (paramsMapObj != null) {
            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(paramsMapObj.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
                @Override
                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            Object value = "";

            ArrayList<String>paramArray = new ArrayList<>();
            for (Map.Entry<String, Object> item : infoIds) {
                String key = item.getKey();
                value = item.getValue();
                if (value instanceof String
                        || value instanceof Integer
                        || value instanceof Float
                        || value instanceof Double
                        || value instanceof Long
                        || value instanceof Boolean) {
                    if (!value.equals("")) {
                        //需要过滤掉空字符串
                        paramArray.add(key+"="+ value);
                    }
                }
            }
            String signString = arrayList2String(paramArray,"&");
            return signString;
        }
        return "";
    }

    // ArrayList类型转成String类型
    private String arrayList2String(ArrayList<String> arrayList, String rex) {
        String result = "";
        if (arrayList != null && arrayList.size() > 0) {
            for (String item : arrayList) {
                // 把列表中的每条数据用逗号分割开来，然后拼接成字符串
                result += item + rex;
            } // 去掉最后一个逗号
            result = result.substring(0, result.length() - 1);
        } return result;
    }



}
